#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
CodeBuddy Keycloak登录脚本
先访问认证页面获取有效参数，然后进行登录
"""

import requests
from urllib.parse import unquote, parse_qs, urlparse
import re
from bs4 import BeautifulSoup

class KeycloakLogin:
    def __init__(self):
        self.session = requests.Session()
        self.setup_headers()
        
    def setup_headers(self):
        """设置浏览器请求头"""
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
            "Accept-Encoding": "gzip, deflate, br",
            "DNT": "1",
            "Connection": "keep-alive",
            "Upgrade-Insecure-Requests": "1",
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "none",
            "Sec-Fetch-User": "?1",
            "sec-ch-ua": '"Not;A=Brand";v="99", "Microsoft Edge";v="139", "Chromium";v="139"',
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": '"Windows"'
        })
    
    def get_keycloak_auth_page(self):
        """访问Keycloak认证页面获取登录表单"""
        print("🔐 正在访问Keycloak认证页面...")
        
        try:
            # 访问Keycloak认证入口
            auth_url = "https://www.codebuddy.ai/auth/realms/copilot"
            response = self.session.get(auth_url, allow_redirects=True)
            
            print(f"📊 状态码: {response.status_code}")
            print(f"🔗 当前URL: {response.url}")
            
            if response.status_code == 200:
                print("✅ 成功访问Keycloak认证页面")
                return response
            else:
                print(f"❌ 访问失败，状态码: {response.status_code}")
                return None
                
        except Exception as e:
            print(f"❌ 访问Keycloak认证页面失败: {e}")
            return None
    
    def get_login_form_url(self):
        """获取登录表单URL"""
        print("📋 正在获取登录表单URL...")
        
        try:
            # 尝试访问控制台，应该会重定向到登录页面
            console_url = "https://www.codebuddy.ai/console"
            response = self.session.get(console_url, allow_redirects=True)
            
            print(f"📊 状态码: {response.status_code}")
            print(f"🔗 最终URL: {response.url}")
            
            if "auth/realms/copilot" in response.url:
                print("✅ 成功重定向到登录页面")
                
                # 解析登录页面获取表单信息
                soup = BeautifulSoup(response.text, 'html.parser')
                
                # 查找登录表单
                login_form = soup.find('form', {'id': 'kc-form-login'})
                if not login_form:
                    login_form = soup.find('form')
                
                if login_form:
                    form_action = login_form.get('action')
                    if form_action:
                        if form_action.startswith('/'):
                            form_action = "https://www.codebuddy.ai" + form_action
                        
                        print(f"📝 找到登录表单URL: {form_action}")
                        return form_action, response
                    else:
                        print("❌ 未找到表单action属性")
                else:
                    print("❌ 未找到登录表单")
                    
                # 如果当前URL就是登录action URL，直接使用
                if "login-actions/authenticate" in response.url:
                    print("📝 当前URL就是登录action URL")
                    return response.url, response
                    
            else:
                print("❌ 未重定向到认证页面")
                
            return None, None
            
        except Exception as e:
            print(f"❌ 获取登录表单URL失败: {e}")
            return None, None
    
    def perform_login(self, login_url):
        """执行登录操作"""
        print("🚀 开始执行登录...")
        
        # 用户凭据
        username = "154hdgrkk7@dpmurt.my"
        password = "5gHpr0V!"
        
        print(f"👤 用户名: {username}")
        print(f"🔑 密码: {password}")
        
        # 准备登录数据
        login_data = {
            "username": username,
            "password": password,
            "credentialId": ""
        }
        
        # 设置登录请求头
        login_headers = {
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
            "Cache-Control": "max-age=0",
            "Content-Type": "application/x-www-form-urlencoded",
            "Origin": "https://www.codebuddy.ai",
            "Referer": login_url,
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1",
            "Upgrade-Insecure-Requests": "1"
        }
        
        try:
            # 发送登录请求
            response = self.session.post(
                login_url,
                data=login_data,
                headers=login_headers,
                allow_redirects=True,
                timeout=30
            )
            
            print(f"📊 登录响应状态码: {response.status_code}")
            print(f"🔗 登录后URL: {response.url}")
            print(f"📏 响应长度: {len(response.text)} 字符")
            
            return self.analyze_login_result(response)
            
        except Exception as e:
            print(f"❌ 登录请求失败: {e}")
            return False
    
    def analyze_login_result(self, response):
        """分析登录结果"""
        print("\n🔍 分析登录结果...")
        
        final_url = response.url.lower()
        response_text = response.text.lower()
        
        # 成功指标
        success_indicators = [
            "console" in final_url and "account" in final_url,
            "dashboard" in final_url,
            "welcome" in response_text,
            response.status_code == 200 and "error" not in final_url
        ]
        
        # 失败指标
        failure_indicators = [
            "error" in final_url,
            "invalid" in response_text,
            "incorrect" in response_text,
            "login" in final_url and "action" in final_url,
            response.status_code >= 400
        ]
        
        if any(success_indicators) and not any(failure_indicators):
            print("✅ 登录成功！")
            self.display_success_info(response)
            return True
        elif any(failure_indicators):
            print("❌ 登录失败")
            self.display_failure_info(response)
            return False
        else:
            print("⚠️ 登录状态不确定")
            self.display_uncertain_info(response)
            return None
    
    def display_success_info(self, response):
        """显示登录成功信息"""
        print("🎉 登录成功详情:")
        print(f"  - 最终URL: {response.url}")
        print(f"  - 状态码: {response.status_code}")
        
        # 显示cookies
        if self.session.cookies:
            print(f"  - 获取到 {len(self.session.cookies)} 个cookies:")
            for cookie in self.session.cookies:
                print(f"    * {cookie.name}: {cookie.value[:30]}...")
    
    def display_failure_info(self, response):
        """显示登录失败信息"""
        print("❌ 登录失败详情:")
        print(f"  - 最终URL: {response.url}")
        print(f"  - 状态码: {response.status_code}")
        
        # 查找错误信息
        if "error" in response.text.lower():
            soup = BeautifulSoup(response.text, 'html.parser')
            error_elements = soup.find_all(['div', 'span', 'p'], class_=re.compile(r'error|alert|message'))
            
            if error_elements:
                print("  - 错误信息:")
                for element in error_elements[:3]:  # 只显示前3个错误信息
                    error_text = element.get_text().strip()
                    if error_text and len(error_text) < 200:
                        print(f"    * {error_text}")
    
    def display_uncertain_info(self, response):
        """显示不确定状态信息"""
        print("⚠️ 状态不确定详情:")
        print(f"  - 最终URL: {response.url}")
        print(f"  - 状态码: {response.status_code}")
        print("  - 建议手动检查响应内容")
    
    def test_authenticated_access(self):
        """测试是否能访问需要认证的页面"""
        print("\n🔐 测试认证状态...")
        
        test_urls = [
            "https://www.codebuddy.ai/console",
            "https://www.codebuddy.ai/console/accounts"
        ]
        
        for url in test_urls:
            try:
                response = self.session.get(url, allow_redirects=True)
                print(f"📊 {url} - 状态码: {response.status_code}")
                
                if response.status_code == 200 and "login" not in response.url.lower():
                    print(f"✅ 能够访问: {url}")
                    return True
                else:
                    print(f"❌ 无法访问: {url}")
                    
            except Exception as e:
                print(f"❌ 测试 {url} 失败: {e}")
        
        return False
    
    def run_complete_login_flow(self):
        """运行完整的登录流程"""
        print("=" * 60)
        print("🎯 CodeBuddy Keycloak完整登录流程")
        print("=" * 60)
        
        # 步骤1: 访问Keycloak认证页面
        auth_response = self.get_keycloak_auth_page()
        if not auth_response:
            print("❌ 无法访问Keycloak认证页面，终止流程")
            return False
        
        # 步骤2: 获取登录表单URL
        login_url, login_page_response = self.get_login_form_url()
        if not login_url:
            print("❌ 无法获取登录表单URL，终止流程")
            return False
        
        # 步骤3: 执行登录
        login_success = self.perform_login(login_url)
        
        # 步骤4: 测试认证状态
        if login_success:
            auth_test = self.test_authenticated_access()
            if auth_test:
                print("\n🎉 完整登录流程成功！")
                return True
        
        print("\n❌ 登录流程失败")
        return False

def main():
    """主函数"""
    login_client = KeycloakLogin()
    success = login_client.run_complete_login_flow()
    
    print("\n" + "=" * 60)
    print("📋 最终结果")
    print("=" * 60)
    
    if success:
        print("✅ 登录成功！CodeBuddy账户已通过认证")
    else:
        print("❌ 登录失败！请检查用户凭据或网络连接")
    
    print("\n💡 说明:")
    print("此脚本通过以下步骤进行登录:")
    print("1. 访问Keycloak认证页面建立session")
    print("2. 获取有效的登录表单URL和参数")
    print("3. 使用正确的凭据执行登录")
    print("4. 验证登录状态和访问权限")

if __name__ == "__main__":
    main()